package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.PropertyRoleGetPageDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyUserLoginDTO;
import com.itlong.cloud.POJO.PO.PropertyFunctionPO;
import com.itlong.cloud.POJO.PO.PropertyRolePO;
import com.itlong.cloud.POJO.PO.PropertyRoleProjectPO;
import com.itlong.cloud.POJO.VO.operate.OperateGetRoleMenuVO;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.PropertyPublicRoleEnum;
import com.itlong.cloud.enumerate.RolePubTypeEnum;
import com.itlong.cloud.property.dao.IPropertyFunctionDao;
import com.itlong.cloud.property.dao.IPropertyRoleDao;
import com.itlong.cloud.property.dao.IPropertyUserInfoDao;
import com.itlong.cloud.property.service.IPropertyRoleService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 *      角色信息业务接口实现类
 * </desc>
 *
 * @createDate 2017/09/25
 */
@Service
public class PropertyRoleServiceImpl implements IPropertyRoleService{

    @Autowired
    IPropertyRoleDao iPropertyRoleDao;

    @Autowired
    IPropertyFunctionDao iPropertyFunctionDao;

    @Autowired
    IPropertyUserInfoDao iPropertyUserInfoDao;

    //Redis工具接口类
    @Autowired
    private RedisService<PropertyUserCacheVO> redisService;

    //RabbitMQ消息队列生产者
    @Autowired
    private MessageSender messageSender;

    /**
     * <desc>
     *      获取物业管理员角色 ：集团物业管理员，物业管理员，独立开发者
     * </desc>
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyRolePO> getRootRoles() {
        return iPropertyRoleDao.getRootRoles();
    }

    /**
     * <desc>
     *      保存角色菜单资源
     * </desc>
     *
     * @param roleId 角色id
     * @param functionIds 资源id 多个,号分隔
     * @param projectId 项目id
     * @return
     * @author Jiaqi.X
     * @version 1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer saveRoleFunction(String roleId, String functionIds, String projectId, String propertyApp) throws Exception {

        //删除之前的角色菜单 物理删除
        //iPropertyFunctionDao.deleteRoleFunctions(roleId,projectId);
        List<String> idList = null;
        if (StringUtils.isNotEmpty(roleId) && StringUtils.isNotEmpty(projectId)) {
            Map<String, Object> params = new HashMap<>();
            params.put("roleId", roleId);
            params.put("projectId", projectId);
            idList = iPropertyRoleDao.getRoleFunctionIdsByParams(params);
        }

        //保存
        Integer saveCount = null;
        if (StringUtils.isNotBlank(functionIds)) {
            Map<String, Object> param = new HashMap<>();
            param.put("roleId", roleId);
            param.put("functionIds", StringHandlerUtil.splitString(functionIds));
            param.put("projectId", projectId);
            param.put("createTime", new Date());
            param.put("status", DataStatusEnum.NORMAL.getType());
            saveCount = iPropertyRoleDao.saveRoleFunction(param);
        }

        if (idList != null && !idList.isEmpty()) {
            iPropertyRoleDao.deleteRoleFunctionById(idList);
        }
        PropertyRolePO propertyRolePO = new PropertyRolePO();
        propertyRolePO.setRoleId(roleId);
        propertyRolePO.setUpdateTime(new Date());
        propertyRolePO.setPropertyApp(StringHandlerUtil.strToIntDef(propertyApp, 0));
        iPropertyRoleDao.update(SqlUtil.durableData(propertyRolePO, PlatformConstants.TABLE_UPDATE));
        return saveCount;
    }





    /**
     * <desc>
     *      保存角色:
     * </desc>
     *
     * @param propertyRoleGetPageDTO 角色实体
     * @return sql执行行数
     * @author Biao.R
     * @createDate 2017/09/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer save(PropertyRoleGetPageDTO propertyRoleGetPageDTO) throws Exception {
        Date currentTime = new Date();
        propertyRoleGetPageDTO.setRoleId(LogicIdUtil.bussinessId());
        Integer status = propertyRoleGetPageDTO.getStatus();
        String maxNum = iPropertyRoleDao.getMaxNum(propertyRoleGetPageDTO.getProjectId());
        //自动补零
        propertyRoleGetPageDTO.setRoleNum(String.format("%04d", Integer.valueOf(maxNum) + 1));
        PropertyRolePO propertyRolePO = new PropertyRolePO();
        BeanUtils.copyProperties(propertyRoleGetPageDTO, propertyRolePO);
        propertyRolePO.setCreateTime(currentTime);
        propertyRolePO.setPubType(RolePubTypeEnum.NOPUBROLE.getType());
        propertyRolePO.setStatus(status==null?DataStatusEnum.NORMAL.getType():status);
        int result = iPropertyRoleDao.save(SqlUtil.durableData(propertyRolePO, PlatformConstants.TABLE_SAVE));
        //添加项目-角色中间表
        PropertyRoleProjectPO projectRole = new PropertyRoleProjectPO(propertyRoleGetPageDTO.getProjectId(), propertyRoleGetPageDTO.getRoleId());
        projectRole.setCreateTime(currentTime);
        projectRole.setStatus(DataStatusEnum.NORMAL.getType());
        result += iPropertyRoleDao.save(SqlUtil.durableData(projectRole, PlatformConstants.TABLE_SAVE));
        return result;
    }


    /**
     * <desc>
     *      更新角色
     * </desc>
     *
     * @param   propertyRoleGetPageDTO 资源角色实体
     * @return sql执行行数
     * @author Biao.R
     * @createDate 2017/09/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer update(PropertyRoleGetPageDTO propertyRoleGetPageDTO) throws Exception {
        PropertyRolePO propertyRolePO = new PropertyRolePO();
        BeanUtils.copyProperties(propertyRoleGetPageDTO, propertyRolePO);
        Integer status = propertyRoleGetPageDTO.getStatus() == null ? DataStatusEnum.NORMAL.getType() : propertyRoleGetPageDTO.getStatus();
        propertyRolePO.setUpdateTime(new Date());
        propertyRolePO.setStatus(status);
        Integer update = iPropertyRoleDao.update(SqlUtil.durableData(propertyRolePO, PlatformConstants.TABLE_UPDATE));

        if (DataStatusEnum.NORMAL.getType() != status) {
            //如果是禁用角色，则该角色下的物业账号已经登陆，需要清除缓存，使其下线
            List<String> cacheKeyList = new ArrayList<>();
            Map<String, Object> params = new HashMap<>();
            params.put("roleId", propertyRoleGetPageDTO.getRoleId());
            params.put("projectId", propertyRoleGetPageDTO.getProjectId());
            List<PropertyRoleProjectPO> roleProjects = iPropertyUserInfoDao.getRoleProject(params);
            if (roleProjects != null && !roleProjects.isEmpty()) {
                for (PropertyRoleProjectPO roleProject : roleProjects) {
                    String userId = roleProject.getUserId();
                    if(StringUtils.isNotEmpty(userId)){
                    cacheKeyList.add(String.format("%s%s", RedisConstant.PROPERTY_USER_REDIS_KEY, userId));
                    }
                }
            }
            if (!cacheKeyList.isEmpty()) {
                JSONObject js = new JSONObject();
                js.put("data",cacheKeyList);
                messageSender.send(RabbitMQConstant.RABBITMQ_DELETE_CACHE_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_USER_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_DELETE_CACHE_KEY);
            }
        }
        return update;
    }

    /**
     * <desc>
     *      通过id获取角色
     * </desc>
     *
     * @param propertyRolePO 角色实体
     * @return 角色实体
     * @author Biao.R
     * @createDate 2017/09/25
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyRolePO getOne(PropertyRolePO propertyRolePO) {
        return iPropertyRoleDao.getOne(propertyRolePO);
    }

    /**
     * <desc>
     *      获取分页数据
     * </desc>
     *
     * @param pageDTO 查询参数DTO
     * @return page模型
     * @author Biao.R
     * @createDate 2017/09/25
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyRoleVO> getPage(PropertyRoleGetPageDTO pageDTO) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为20
        Page<PropertyRoleVO> page = new Page<>();
        page.getPage().setPageSize(pageDTO.getPageSize());
        page.getPage().setCurrentPage(pageDTO.getCurrentPage());
        params.put("projectId",pageDTO.getProjectId());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        //List<PropertyRoleVO> pageList = iPropertyRoleDao.getPageList(params);
        page.setRows(iPropertyRoleDao.getPageList(params), iPropertyRoleDao.getPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      删除角色
     * </desc>
     *
     * @param roleIds 角色id数组
     * @return sql执行行数
     * @author Biao.R
     * @createDate 2017/09/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer delete(String roleIds) {
        try {
            String[] roleIdArr = StringHandlerUtil.splitString(roleIds);
            int deleteCount = 0;
            if (roleIdArr.length > 0) {
                deleteCount = iPropertyRoleDao.delete(roleIdArr, new Date());

                //如果该角色下的物业账号已经登陆，需要清除缓存，使其下线
                List<String> cacheKeyList = new ArrayList<>();
                for (String roleId : roleIdArr) {
                    Map<String, Object> params = new HashMap<>();
                    params.put("roleId", roleId);
                    List<PropertyRoleProjectPO> roleProjects = iPropertyUserInfoDao.getRoleProject(params);
                    if (roleProjects != null && !roleProjects.isEmpty()) {
                        for (PropertyRoleProjectPO roleProject : roleProjects) {
                            cacheKeyList.add(String.format("%s%s", RedisConstant.PROPERTY_USER_REDIS_KEY, roleProject.getUserId()));
                            //清除物业app登录缓存，否则无法查询到用户的角色信息将报错
                            cacheKeyList.add(String.format("%s%s",RedisConstant.PROPERTY_APP_REDIS_USER_KEY,roleProject.getUserId()));
                        }
                    }
                }
                if (!cacheKeyList.isEmpty()) {
                    JSONObject datajs = new JSONObject();
                    datajs.put("data",cacheKeyList);
                    messageSender.send(RabbitMQConstant.RABBITMQ_DELETE_CACHE_QUEUE, JsonUtil.toJSON(datajs), RabbitMQConstant.RABBITMQ_USER_EXCHANGE,
                            RabbitMQConstant.RABBITMQ_DELETE_CACHE_KEY);
                }
                deleteCount += iPropertyUserInfoDao.deleteRoleProject(roleIdArr);       // 不物理删除角色用户项目信息，否则会导致用户列表无法展示
                // 物理删除角色菜单关系
                deleteCount += iPropertyUserInfoDao.deleteRoleFunction(roleIdArr);
            }
            return deleteCount;
        } catch (Exception e) {
            throw new DataAccessException("【物业角色服务层_PropertyRoleServiceImpl_delete】删除物业角色异常", e);
        }
    }

    /**
     * <desc>
     *      保存角色菜单资源
     * </desc>
     *
     * @param roleId 角色id
     * @param functionIds 资源id 多个,号分隔
     * @return
     * @author Biao.R
     * @version 1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer saveRoleFunction(String roleId, String functionIds) {
        //删除之前的角色菜单 物理删除
        iPropertyFunctionDao.deleteRoleFunctions(roleId,"");
        //保存
        Map<String,Object> param = new HashMap<>();
        param.put("roleId",roleId);
        param.put("functionIds",StringHandlerUtil.splitString(functionIds));
        param.put("status",DataStatusEnum.NORMAL.getType());
        param.put("createTime",new Date());
        return iPropertyRoleDao.saveRoleFunction(param);
    }


    /**
     * <desc>
     *       为角色分配人员
     * </desc>
     *
     * @param roleId    角色id
     * @param allotUsers    需要分配的人员id 多个，号分隔
     * @param userIds 当前列表所有人员id 多个，号分隔
     * @return sql执行行数
     * @author Biao.R
     * @createDate 2017/10/10
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer saveRoleUsers(String roleId, String allotUsers, String userIds) {
        //防止绕过前端提交，工程人员不可编辑
        if (roleId != null && !roleId.equals("1")) {
            //先将用户的角色置为''，涉及两张表
            if (StringUtils.isNotEmpty(userIds)) {
                iPropertyRoleDao.deleteRoleUsers(StringHandlerUtil.splitString(userIds), roleId);
            }
            //为用户分配角色
            if (StringUtils.isNotEmpty(allotUsers)) {
                Map<String, Object> params = new HashMap<>();
                params.put("allotUsers", StringHandlerUtil.splitString(allotUsers));
                params.put("roleId", roleId);
                params.put("updateTime", new Date());
                params.put("status", DataStatusEnum.NORMAL.getType());
                return iPropertyRoleDao.saveRoleUsers(params);
            }
        }
        return 1;
    }


    /**
     * <desc>
     *       根据字段参数查询
     * </desc>
     *
     * @param params    查询参数
     * @return List<PropertyRolePO> 返回数据集合
     * @author Biao.R
     * @createDate 2017/10/17
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyRolePO> getByFields(Map<String, Object> params) {
        return iPropertyRoleDao.getByParams(params);
    }

    /**
     * <desc>
     *      角色分配菜单按钮权限前，查询角色菜单和按钮
     *      角色的菜单权限不能超出物业管理员的菜单和按钮权限
     * <desc/>
     * @param   propertyRoleGetPageDTO  物业角色查询对象
     * @return
     * @author Biao.R
     * @createDate 2017/10/26
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyParentFunctionVO> getRoleFunctions(PropertyRoleGetPageDTO propertyRoleGetPageDTO) {
        List<PropertyParentFunctionVO> parentMenuList = new ArrayList<>();
        //先查找该小区物业管理员拥有的菜单权限
        Map<String, Object> params = new HashMap<>();
        String projectId = propertyRoleGetPageDTO.getProjectId();
        params.put("projectId", projectId);
        params.put("roleId", PropertyPublicRoleEnum.ADMIN.getRoleId());
        params.put("orderBy","orders DESC");
        List<PropertyFunctionPO> functionList = iPropertyFunctionDao.getFunctionsByRole(params);

        //如果物业管理员没有菜单，查询集团物业管理员的菜单
        if (functionList == null || functionList.isEmpty()) {
            params.put("roleId", PropertyPublicRoleEnum.GROUP_ADMIN.getRoleId());
            functionList = iPropertyFunctionDao.getFunctionsByRole(params);
        }

        if (functionList != null && !functionList.isEmpty()) {
            //查询该角色拥有的菜单ID
            params.put("roleId", propertyRoleGetPageDTO.getRoleId());
            List<String> roleFunctionIds = iPropertyFunctionDao.getFunctionIdsByRole(params);


            //利用linkedList的队列特性，组合菜单层级关系
            LinkedList<PropertyFunctionPO> functionLinkedList = new LinkedList<>(functionList);
            int handlerTimes = 0;
            //为避免有脏数据导致死循环的发生，这里设置循环次数最大为所查出节点个数的2倍
            int maxHandlerTimes = (functionList.size()) * 2;
            while (functionLinkedList != null && !functionLinkedList.isEmpty() && handlerTimes <= maxHandlerTimes) {
                handlerTimes++;
                boolean isAdd = false;
                PropertyFunctionPO parentPO = functionLinkedList.poll();
                String parentId = parentPO.getParent();
                if ("0".equals(parentId)) {
                    //顶级菜单，存放到VOlist
                    PropertyParentFunctionVO parentVO = new PropertyParentFunctionVO(parentId);
                    BeanUtils.copyProperties(parentPO, parentVO);
                    if (roleFunctionIds.contains(parentPO.getFunctionId())) {
                        //如果roleFunctionIds中包含，则选中
                        parentVO.setIsMark(PlatformConstants.DEVICEAUTH_ISCHECKED_YSE);
                    }
                    parentMenuList.add(parentVO);
                    isAdd = true;
                } else {
                    if (!isAdd && !parentMenuList.isEmpty()) {
                        //判断是不是二级菜单或按钮，查询returnFunctions中是否有该二级菜单的父级菜单
                        for (PropertyParentFunctionVO parentMenu : parentMenuList) {
                            List<PropertyChildFunctionVO> childMenuList = parentMenu.getChildFunctionList();
                            if (parentId.equals(parentMenu.getFunctionId())) {
                                //如果该二级菜单的父级菜单已经存在，
                                PropertyChildFunctionVO childVO = new PropertyChildFunctionVO(parentId);
                                BeanUtils.copyProperties(parentPO, childVO);
                                if (roleFunctionIds.contains(parentPO.getFunctionId())) {
                                    //如果roleFunctionIds中包含，则选中
                                    childVO.setIsMark(PlatformConstants.DEVICEAUTH_ISCHECKED_YSE);
                                }
                                childMenuList.add(childVO);
                                isAdd = true;
                            } else {
                                if (!isAdd && !childMenuList.isEmpty()) {
                                    //判断是不是按钮
                                    for (PropertyChildFunctionVO childMenu : childMenuList) {
                                        if (parentId.equals(childMenu.getFunctionId())) {
                                            PropertyButtonFunctionVO buttonVO = new PropertyButtonFunctionVO(parentId);
                                            BeanUtils.copyProperties(parentPO, buttonVO);
                                            if (roleFunctionIds.contains(buttonVO.getFunctionId())) {
                                                //如果roleFunctionIds中包含，则选中
                                                buttonVO.setIsMark(PlatformConstants.DEVICEAUTH_ISCHECKED_YSE);
                                            }
                                            childMenu.getChildFunctionList().add(buttonVO);
                                            isAdd = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (!isAdd) {
                    functionLinkedList.offer(parentPO);
                }
            }


        }
        return parentMenuList;
    }

    /**
     * <desc>
     *      查询角色物业app字段
     * </desc>
     *
     * @author wangzhi
     * @createDate 2019/12/24
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String getRolePropertyApp(PropertyRoleGetPageDTO propertyRoleGetPageDTO) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("roleId", propertyRoleGetPageDTO.getRoleId());
        return iPropertyRoleDao.getRolePropertyApp(params);
    }

    /**
     * <desc>
     *      查询物业角色拥有的一级和二级菜单
     * <desc/>
     * @param  propertyUserLoginDTO 登录DTO
     * @return   查询得到的菜单按钮VO
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<OperateGetRoleMenuVO> getFunctions(PropertyUserLoginDTO propertyUserLoginDTO) {
        List<OperateGetRoleMenuVO> returnFunctions = new ArrayList<>();
        String projectId = propertyUserLoginDTO.getProjectId();
        Map<String, Object> params = new HashMap<>();
        params.put("projectId", propertyUserLoginDTO.getProjectId());
        params.put("roleId", propertyUserLoginDTO.getRoleId());
        params.put("orderBy","orders DESC");
        List<PropertyFunctionPO> functionList = iPropertyFunctionDao.getFunctionsByRole(params);

        //组合层级关系
        LinkedList<PropertyFunctionPO> functionLinkedList = new LinkedList<>(functionList);
        if (functionList != null && !functionList.isEmpty()) {

            int handlerTimes = 0;
            //为避免有脏数据导致死循环的发生，这里设置循环次数最大为所查出节点个数的2倍
            int maxHandlerTimes = (functionList.size()) * 2;
            while (functionLinkedList != null && !functionLinkedList.isEmpty() && handlerTimes <= maxHandlerTimes) {
                handlerTimes++;
                PropertyFunctionPO parentPO = functionLinkedList.poll();
                String parentId = parentPO.getParent();
                String functionUrl = parentPO.getFunctionUrl();
                String identifier = parentPO.getIdentifier();
                String functionId = parentPO.getFunctionId();
                String functionName = parentPO.getFunctionName();
                String icon = parentPO.getIcon();
                Integer orders = parentPO.getOrders();
                OperateGetRoleMenuVO addFunction = null;

                if ("0".equals(parentId)) {
                    //顶级菜单，存放到VOlist
                    addFunction = new OperateGetRoleMenuVO(functionId, StringUtils.isEmpty(functionUrl) ? "/" : functionUrl,
                            StringUtils.isEmpty(identifier) ? "home" : identifier, functionName,
                            "true", icon, "false",orders);
                    returnFunctions.add(addFunction);
                } else {
                    //二级菜单或按钮，查询returnFunctions中是否有该二级菜单的父级菜单
                    if (addFunction == null && !returnFunctions.isEmpty()) {
                        for (OperateGetRoleMenuVO returnVO : returnFunctions) {
                            List<OperateGetRoleMenuVO> returnVOChildren = returnVO.getChildren();
                            if (parentId.equals(returnVO.getFunctionId())) {
                                //如果该二级菜单的父级菜单已经存在，
                                addFunction = new OperateGetRoleMenuVO(functionId, functionUrl, identifier,
                                        functionName, "true", icon, "false",orders);
                                if (returnVOChildren == null || returnVOChildren.isEmpty()) {
                                    List<OperateGetRoleMenuVO> childrens = new ArrayList<>();
                                    childrens.add(addFunction);
                                    returnVO.setChildren(childrens);
                                } else {
                                    returnVOChildren.add(addFunction);
                                }
                            }

                            List<OperateGetRoleMenuVO> childrenMenus = returnVO.getChildren();
                            if (addFunction == null && childrenMenus != null && !childrenMenus.isEmpty()) {
                                for (OperateGetRoleMenuVO childrenMenu : childrenMenus) {
                                    List<OperateGetRoleMenuVO> children = childrenMenu.getChildren();
                                    if (parentId.equals(childrenMenu.getFunctionId())) {
                                        //如果该二级菜单的父级菜单已经存在，
                                        addFunction = new OperateGetRoleMenuVO(functionId, functionUrl, identifier,
                                                functionName, "true", icon, "false",orders);
                                        if (children == null || children.isEmpty()) {
                                            List<OperateGetRoleMenuVO> childrens = new ArrayList<>();
                                            childrens.add(addFunction);
                                            childrenMenu.setChildren(childrens);
                                        } else {
                                            children.add(addFunction);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                //如果addFunction为null,表示parentPO没有被整理，需重新添加到队尾
                if (addFunction == null) {
                    functionLinkedList.offer(parentPO);
                }
            }

            //给二级菜单排序
            for (OperateGetRoleMenuVO returnFunction : returnFunctions) {
                List<OperateGetRoleMenuVO> childrenFunctions = returnFunction.getChildren();
                if(childrenFunctions!=null && !childrenFunctions.isEmpty()){
                    childrenFunctions.sort((OperateGetRoleMenuVO fun1, OperateGetRoleMenuVO fun2) -> fun2.getOrders().compareTo(fun1.getOrders()));
                }
            }
        }
        //切换小区后，需要更新缓存中的小区和角色信息
        String loginUserId = propertyUserLoginDTO.getLoginUserId();
        String cacheKey = String.format("%s%s", RedisConstant.PROPERTY_USER_REDIS_KEY, loginUserId);
        PropertyUserCacheVO propertyUserCacheVO = redisService.getObject(cacheKey, PropertyUserCacheVO.class);
        if (propertyUserCacheVO != null && propertyUserLoginDTO.getToken().equals(propertyUserCacheVO.getToken())) {
            //查询该账号在该小区的角色
            List<PropertyProjectRoleVO> projectRoles = iPropertyUserInfoDao.getProjectRole(propertyUserCacheVO.getUserId(), projectId);
            if (projectRoles != null && !projectRoles.isEmpty()) {
                PropertyProjectRoleVO projectRole = projectRoles.get(0);
                propertyUserCacheVO.setProjectId(projectId);
                propertyUserCacheVO.setProjectName(projectRole.getProjectName());
                propertyUserCacheVO.setRoleId(projectRole.getRoleId());
                propertyUserCacheVO.setRoleName(projectRole.getRoleName());
                String desToken = UserTokenUtil.tokenDecrypt(propertyUserCacheVO.getToken(), PlatformConstants.PROPERTY_USER_TOKEN_KEY);
                if (propertyUserLoginDTO.getLoginUserId().equals(desToken)) {
                    redisService.set(cacheKey, RedisConstant.PROPERTY_LOGIN_TIME, propertyUserCacheVO);
                }
            }
        }
        // 不存在旧角色时不显示角色管理菜单
        Map<String, Object> map = new HashMap<>();
        map.put("projectId", propertyUserLoginDTO.getProjectId());
        Integer oldRoleCount = iPropertyRoleDao.getPageCount(map);
        if (oldRoleCount == 0) {
            for (OperateGetRoleMenuVO vo : returnFunctions) {
                if ("/systemManage".equals(vo.getPath())) {
                    for (OperateGetRoleMenuVO childVO : vo.getChildren()) {
                        if ("/systemManage/role".equals(childVO.getPath())) {
                            vo.getChildren().remove(childVO);
                            break;
                        }
                    }
                    if (vo.getChildren().isEmpty()) {
                        returnFunctions.remove(vo);
                    }
                    break;
                }
            }
        }
        return returnFunctions;
    }



    /**
     * <desc>
     *      点击左边菜单后，根据角色和菜单获取菜单下的按钮集合
     * <desc/>
     * @param   propertyUserLoginDTO     物业用户登录DTO
     * @return  查找到的按钮数据集
     * @author Biao.R
     * @createDate 2017/10/12
     */
    @Override
    public List<OperateGetRoleMenuVO> getAuthBtns(PropertyUserLoginDTO propertyUserLoginDTO) {
        String functionId = propertyUserLoginDTO.getFunctionId();
        String projectId = propertyUserLoginDTO.getProjectId();
        String[] roles = StringHandlerUtil.splitString(propertyUserLoginDTO.getRoleId());
        List<OperateGetRoleMenuVO> list = new ArrayList<>();
        List<PropertyFunctionVO> menus= iPropertyFunctionDao.getFunctionByRoleId(roles, projectId, functionId);
        for (PropertyFunctionVO menu : menus) {
            OperateGetRoleMenuVO vo = new OperateGetRoleMenuVO();
            vo.setPath(menu.getFunctionUrl());
            vo.setName(menu.getFunctionName());
            vo.setComponent(menu.getIdentifier());
            vo.setIconCls(menu.getIcon());
            vo.setHidden("true");
            vo.setLeaf("false");
            list.add(vo);
        }
        return list;
    }

    /**
     * <desc>
     *      根据角色获取菜单按钮的拦截Url
     * <desc/>
     * @param   roleId  当前项目的角色ID
     * @param   projectId  登录令牌
     * @return  查询到的按钮信息
     * @author Biao.R
     * @createDate 2017/11/27
     */
    @Override
    public List<PropertyFunctionPO> getFunctionsByRole(String roleId, String projectId) {
        if (StringUtils.isEmpty(roleId) || StringUtils.isEmpty(projectId)) {
            return null;
        }
        Map<String, Object> params = new HashMap<>();
        params.put("roleId", roleId);
        params.put("projectId", projectId);
        List<PropertyFunctionPO> functionList = iPropertyFunctionDao.getFunctionsByRole(params);
        return functionList;
    }

    /**
     * <desc>
     *      通过component和roleId  反向获取对应菜单functionId
     * <desc/>
     * @param  identifier    操作对应的按钮标识
     * @return  该该按钮所在的菜单ID
     * @author Biao.R
     * @createDate 2017/11/30
     */
    @Override
    public String getFunctionIdByIdentifier(String identifier) {
        if (StringUtils.isNotEmpty(identifier)) {
            return iPropertyFunctionDao.getFunctionIdByIdentifier(identifier);
        }
        return null;
    }

    /**
     * <desc>
     *      查询指定角色所有用户
     * </desc>
     *
     * @param projectId 项目id
     * @param roleId 角色id
     * @return 用户列表
     * @author wangzhi
     * @createDate 2018/08/15
     */
    @Override
    public List<PropertyGetRoleUserVO> getRoleUser(String projectId, String roleId) {
        return iPropertyUserInfoDao.getRoleUser(projectId,roleId);
    }

}
